"""
@Description: 监听某个控件，使窗口随着鼠标移动
"""
from PyQt5.QtCore import Qt, QObject, QEvent
from PyQt5.QtGui import QCursor, QMouseEvent


class MouseMoveFilter(QObject):
    def __init__(self, win):
        super().__init__()
        # 窗口
        self.win = win
        # 监控的组件
        self.watch = None
        # 初始化按下状态
        self.win.press_flag = False

    def mousePressEvent(self, mouseEvent):
        if mouseEvent.button() == Qt.LeftButton:
            self.win.press_flag = True
            self.win.press_position = mouseEvent.globalPos() - self.win.pos()  # 获取鼠标相对窗口的位置
            mouseEvent.accept()
            self.win.setCursor(QCursor(Qt.OpenHandCursor))  # 更改鼠标图标

    def mouseMoveEvent(self, mouseEvent):
        if Qt.LeftButton and self.win.press_flag:
            self.win.move(mouseEvent.globalPos() - self.win.press_position)  # 更改窗口位置
            mouseEvent.accept()

    def mouseReleaseEvent(self, mouseEvent):
        self.win.press_flag = False
        self.win.setCursor(QCursor(Qt.ArrowCursor))

    def eventFilter(self, watched, event):
        # 默认监听所有的控件，这里只监听指定的watch控件
        if watched != self.watch:
            return QObject.eventFilter(self, watched, event)

        # 判断是否是鼠标事件
        mouseEventDict = {QEvent.MouseButtonPress, QEvent.MouseButtonRelease, QEvent.MouseButtonDblClick,
                          QEvent.MouseMove}
        if event.type() not in mouseEventDict:
            return QObject.eventFilter(self, watched, event)

        # 对每个事件进行处理
        mouseEvent = QMouseEvent(event)
        if event.type() == QEvent.MouseButtonPress and mouseEvent.button() == Qt.LeftButton:
            self.mousePressEvent(mouseEvent)
            return True
        if event.type() == QEvent.MouseMove:
            self.mouseMoveEvent(mouseEvent)
            return True
        if event.type() == QEvent.MouseButtonRelease and mouseEvent.button() == Qt.LeftButton:
            self.mouseReleaseEvent(mouseEvent)
            return True
        return QObject.eventFilter(self, watched, event)
